<?php

namespace App\Http\Requests\Products;

use App\Http\Requests\ApiRequest;
use App\Models\Extension\Extension;
use App\Models\Layout\LayoutModule;
use App\Models\Layout\Module;
use Illuminate\Validation\Validator;

/**
 * @property string $category_id
 * @property string $stock_status_id
 * @property string $manufacturer_ids
 * @property string $option_value_ids
 * @property string $keyword
 * @property string $attributes
 * @property array $price_range
 * @property string|null search_type
 * @property string|null layout_module_id
 * @property string|null module_id
 */
class ProductIndexRequest extends ApiRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $rules = [
            'category_id'      => 'nullable|int|min:1|max:' . self::MAX_INT,
            'stock_status_id'  => 'nullable|int|min:1|max:' . self::MAX_INT,
            'keyword'          => 'nullable|string|min:1|max:' . self::MAX_STRING,
            'manufacturer_ids' => 'nullable|string|min:1',
            'option_value_ids' => 'nullable|string|min:1',
            'attributes'                => 'nullable|array',
            'attributes.*'              => 'required|array',
            'attributes.*.attribute_id' => 'required|int|min:1|max:' . self::MAX_INT,
            'attributes.*.text'         => 'required|string|max:' . self::MAX_STRING,
            'price_range'   => 'sometimes|required|array|size:2',
            'price_range.*' => 'required|numeric',

            // 搜索更多商品的参数
            'search_type'      => 'nullable|string|in:bestseller,special,latest,featured',
            'module_id'        => 'int|min:1',
            'layout_module_id' => 'int|min:1',
        ];

        return $rules;
    }

    public function manufacturerIds(): ?array
    {
        return $this->manufacturer_ids
            ? explode(',', $this->manufacturer_ids)
            : null;
    }

    public function optionValueIds(): ?array
    {
        return $this->option_value_ids
            ? explode(',', $this->option_value_ids)
            : null;
    }

    /**
     * @param Validator $validator
     * @throws \App\Exceptions\ApiException
     * @throws \App\Exceptions\ApiSilentException
     */
    protected function afterValidator(Validator $validator)
    {
        $this->checkSearchType();
    }

    /**
     * @throws \App\Exceptions\ApiException
     * @throws \App\Exceptions\ApiSilentException
     */
    private function checkSearchType()
    {
        if ($this->search_type === Extension::CODE_FEATURED) {
            $this->module();
        }
    }

    /**
     * @throws \App\Exceptions\ApiException
     * @throws \App\Exceptions\ApiSilentException
     */
    public function module(): Module
    {
        if ($this->layout_module_id) {
            return $this->layoutModule()->module;
        }

        $module =  Module::memoWhereFirst([
            'module_id' => $this->module_id,
        ]);

        if (! $module) {
            $this->validatorFailed('module_id', 'Exists');
        }

        return $module;
    }

    /**
     * @throws \App\Exceptions\ApiException
     * @throws \App\Exceptions\ApiSilentException
     */
    public function layoutModule(): LayoutModule
    {
        $module =  LayoutModule::memoWhereFirst([
            'layout_module_id' => $this->layout_module_id,
//            'code'      => $this->search_type,
        ]);

        if (! $module) {
            $this->validatorFailed('layout_module_id', 'Exists');
        }

        return $module;
    }
}
